#pragma once
#include "yzrutil.h"
#include "collection/Iterator.hpp"
#include "lang/Exception.h"

namespace yzrilyzr_collection {
	template<typename E>
	class Iterable;

	template<typename E>
	class IteratorWrap {
	private:
		std::unique_ptr<Iterator<E>> itr; // 独占所有权，仅支持移动
		bool is_end;                     // 标记是否为 end 迭代器
		E *current_val;                  // 指向当前元素的指针（确保初始化）

	public:
		// 普通构造：从 Iterable 创建迭代器（is_end=false 表示 begin，true 表示 end）
		IteratorWrap(const Iterable<E> *cparent, Iterable<E> *parent, bool is_end) : is_end(is_end),
																					 current_val(
																							 nullptr) { // 初始化 current_val
			// 获取 const 迭代器
			if (parent != nullptr)itr = parent->iterator();
			else if (cparent != nullptr)itr = cparent->constIterator();

			// 仅当是 begin 迭代器时，初始化 current_val（不跳过第一个元素）
			if (!is_end) {
				if (itr->hasNext()) {
					current_val = &itr->next();
				} else {
					// 空容器的 begin() 就是 end()
					this->is_end = true;
				}
			}
		}
		IteratorWrap(const IteratorWrap &) = delete;
		// 禁止拷贝赋值
		IteratorWrap &operator=(const IteratorWrap &) = delete;

		// 允许移动构造
		IteratorWrap(IteratorWrap &&other) noexcept: itr(std::move(other.itr)),
													 is_end(other.is_end),
													 current_val(other.current_val) {
			// 移动后，将源对象的 current_val 置空（避免悬空指针）
			other.current_val = nullptr;
			other.is_end = true; // 源对象变为 end 状态，避免重复访问
		}

		// 允许移动赋值
		IteratorWrap &operator=(IteratorWrap &&other) noexcept {
			if (this != &other) {
				itr = std::move(other.itr);
				is_end = other.is_end;
				current_val = other.current_val;

				// 重置源对象
				other.current_val = nullptr;
				other.is_end = true;
			}
			return *this;
		}

		// 前置递增：++itr（无参数，返回引用）
		IteratorWrap &operator++() {
			// 如果已是 end，递增无意义
			if (is_end) {
				return *this;
			}

			// 检查是否有下一个元素
			if (itr->hasNext()) {
				current_val = &itr->next();
			} else {
				// 没有下一个元素，标记为 end
				is_end = true;
				current_val = nullptr; // 避免悬空指针
			}
			return *this;
		}

		// 后置递增：itr++（必须带 int 参数，返回副本）
		IteratorWrap operator++(int) { // 参数改为 int（占位）
			IteratorWrap temp(std::move(*this)); // 移动构造临时对象（因无拷贝）
			++(*this); // 递增当前对象
			return temp; // 返回递增前的临时对象
		}

		// 解引用：*itr（返回当前元素的引用）
		E &operator*() const {
			// 检查迭代器是否有效（非 end 且 current_val 非空）
			if (is_end || current_val == nullptr) {
				throw yzrilyzr_lang::IllegalStateException("Dereference end iterator");
			}
			return *current_val;
		}

		// 箭头运算符：itr->（支持访问元素成员，如 itr->field）
		E *operator->() const {
			return &operator*(); // 复用解引用逻辑
		}

		// 相等：仅当“同一迭代器且状态相同”时相等（简化版，严格版需比较迭代器位置）
		bool operator==(const IteratorWrap<E> &other) const {
			// 若两个都是 end，判定为相等（简化逻辑，适用于范围 for）
			if (is_end && other.is_end) {
				return true;
			}
			// 若一个是 end 一个不是，判定为不相等
			if (is_end != other.is_end) {
				return false;
			}
			// （可选）严格比较：若迭代器支持，可比较当前位置（如索引）
			// 这里简化为“同一迭代器对象”（通过 itr 地址，但 unique_ptr 移动后地址会变，需谨慎）
			return itr.get() == other.itr.get() && current_val == other.current_val;
		}

		bool operator!=(const IteratorWrap<E> &other) const {
			return !(*this == other);
		}

		// -------------------------- 6. 辅助接口：判断是否为 end --------------------------
		bool isEnd() const {
			return is_end;
		}
	};

	template<typename E>
	EBCLASS(Iterable) {
	public:
		Iterable() = default;
		~Iterable() override = default;
		virtual std::unique_ptr<Iterator<E>> iterator() = 0;
		virtual std::unique_ptr<Iterator<E>> constIterator() const = 0;
		IteratorWrap<E> begin() const {
			return IteratorWrap<E>(this, nullptr, false);
		}
		IteratorWrap<E> end() const {
			return IteratorWrap<E>(this, nullptr, true);
		}
		IteratorWrap<E> begin() {
			return IteratorWrap<E>(this, this, false);
		}
		IteratorWrap<E> end() {
			return IteratorWrap<E>(this, this, true);
		}
		IteratorWrap<E> find(const E &v) const {
			IteratorWrap<E> it = begin();
			IteratorWrap<E> e = end();
			for (; it != e; ++it) {
				if (*it == v) {
					return it;
				}
			}
			return e;
		}
	};
}